#include <iostream>
using namespace std;
/*
    抽象类：
        具有纯虚函数的类叫做抽象类。虚函数初始化为0
        抽象类不能实例化对象：不能定义对象
*/
class Exception
{
public:
    virtual string what() const = 0;
};

class DivideException : public Exception
{
public:
    string what() const
    {
        return "不能除以0";
    }
};
class MemoryException : public Exception
{
public:
    string what() const
    {
        return "内存溢出";
    }
};
int divide(int val1, int val2) noexcept(false)
{
    if (val2 == 0)
    {
        /*如果当前文件没有catch捕捉异常，跳到上一级找，最上一层没有，程序结束*/
        throw DivideException();
    }
    return val1 / val2;
}
int simulateNewException() noexcept(false)
{
    try
    {
        /* code */
        int *p = new int[99999999999];
    }
    // catch (const std::exception &e)
    catch (const std::bad_alloc &e)
    {
        cout << "内存溢出\n";
        std::cerr << e.what() << '\n';
    }
    return 0;
}
class Person
{
public:
    Person()
    {
        cout << "Person 构造函数\n";
    }

    virtual void run()
    {
        cout << "Person run\n";
    }

public:
    int m_age;
};
class Student : public Person
{
public:
    Student()
    {
        cout << "Student 构造函数\n";
    }
    void run()
    {
        cout << "Student run\n";
    }

public:
    int m_score;
};
int simulateDynamicCastException()
{
    Person *p1 = new Person();  /*自己指向自己*/
    Person *p2 = new Student(); /*父类指针指向子类对象*/
    /*test*/
    Person &p3 = *p1;
    try
    {
        /*这个不算异常：安全监测不算异常*/
        Student *stu1 = dynamic_cast<Student *>(p1);
        cout << stu1 << endl;
    }
    catch (const std::bad_cast &e)
    {
        std::cerr << e.what() << '\n';
    }
    try
    {
        /* code */
        Student *stu2 = dynamic_cast<Student *>(p2);
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what() << '\n';
    }
    try
    {
        /* 引用才可以抛异常*/
        Student &stu = dynamic_cast<Student &>(p3);
    }
    catch (const std::bad_cast &e)
    {
        std::cerr << e.what() << '\n';
    }

    return 0;
}
int main()
{
#if 0
    /*引用要有初始值*/
    Exception &ex=;
#endif
    simulateDynamicCastException();
    // simulateNewException();
    // try
    // {

    //     int val1 = 100;
    //     int val2 = 0;
    //     int res = divide(val1, val2);
    //     cout << "res==" << res << endl;
    // }
    // catch (const Exception &e)
    // {
    //     cout << e.what() << '\n';
    // }
    cout << "hello world\n";
    return 0;
}